//============================================================================
// Name        : worklist.h
// Author      : Yugi
// Version     : 1.0
// Description : 
//============================================================================

#ifndef _WORKLIST_H
#define _WORKLIST_H

#include <stdlib.h>
#include <dr_api.h>

/* Structure of worklist node */
typedef struct _NODE{
	opnd_t value;		// node value
	struct _NODE *prev;	// previous node
	struct _NODE *next; // next node
} NODE, *PNODE;

/* Structure of worklist */
typedef struct _WORKLIST{
	PNODE head;			// list head
	PNODE tail;			// list tail
	unsigned int size;	// list size
} WORKLIST, *PWORKLIST;

/* 
* Generate a worklist.
* 
* RETURN:	new worklist
* NOTES:	Return value should be freed by user
*/
PWORKLIST wl_new();

/* 
* Make a copy of the input worklist
* 
* RETURN:	clone of src
* NOTES:	Return value should be freed by user
*/
PWORKLIST wl_clone(PWORKLIST src);

/* 
* Merge worklists
*
* REQUIRE:	pList1, pList2 not NULL
* NOTES:	Return value should be freed by user
*/
PWORKLIST wl_merge(PWORKLIST pList1, PWORKLIST pList2);

/* 
* pList1 contains pList2
*
* REQUIRE:	pList1, pList2 not NULL
* NOTES:	Return value should be freed by user
*/
bool wl_subset(PWORKLIST pList1, PWORKLIST pList2);

/* 
* Free the input worklist
*
* REQUIRE:	src not NULL
*/
void wl_delete(PWORKLIST pList);

/* 
* Add a node with 'value' to the end of 'pList'.
* 
* REQUIRE:	pList not NULL
* MODIFY:	pList
*/
void wl_append(PWORKLIST pList, opnd_t value);

/* 
* Test if 'pList' contains value.
*
* REQUIRE:	pList not NULL
* RETURN:	true if 'pList' contains value, false otherwise
* NOTES:	Only registers and base-disp operands will be tested
*/
bool wl_contain(PWORKLIST pList, opnd_t value);

/* 
* Remove node with 'value' from 'pList'. 
*
* REQUIRE:	pList not NULL
* RETURN:	true if 'pList' contains value, false otherwise
* MODIFY:	pList
* NOTES:	Only registers and base-disp operands will be removed.
*/
bool wl_kill(PWORKLIST, opnd_t);

/* 
* Insert node  with 'value' into 'pList'
*
* REQUIRE:	pList not NULL
* RETURN:	true if 'pList' does not contain value, false otherwise
* MODIFY:	pList
* NOTES:	Only registers and base-disp operands will be added.
*/
bool wl_gen(PWORKLIST, opnd_t);

/* Print a worklist using <opnd_disassemble> */
void wl_print(void *drcontext, PWORKLIST pList, file_t outfile);

#endif /* End of _WORKLIST_H */